import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:stac/src/utils/color_utils.dart';

part 'stac_color_scheme.freezed.dart';
part 'stac_color_scheme.g.dart';

@freezed
abstract class StacColorScheme with _$StacColorScheme {
  const factory StacColorScheme({
    required Brightness brightness,
    required String primary,
    required String onPrimary,
    String? primaryContainer,
    String? onPrimaryContainer,
    String? primaryFixed,
    String? primaryFixedDim,
    String? onPrimaryFixed,
    String? onPrimaryFixedVariant,
    required String secondary,
    required String onSecondary,
    String? secondaryContainer,
    String? onSecondaryContainer,
    String? secondaryFixed,
    String? secondaryFixedDim,
    String? onSecondaryFixed,
    String? onSecondaryFixedVariant,
    String? tertiary,
    String? onTertiary,
    String? tertiaryContainer,
    String? onTertiaryContainer,
    String? tertiaryFixed,
    String? tertiaryFixedDim,
    String? onTertiaryFixed,
    String? onTertiaryFixedVariant,
    required String error,
    required String onError,
    String? errorContainer,
    String? onErrorContainer,
    required String surface,
    required String onSurface,
    String? surfaceDim,
    String? surfaceBright,
    String? surfaceContainerLowest,
    String? surfaceContainerLow,
    String? surfaceContainer,
    String? surfaceContainerHigh,
    String? surfaceContainerHighest,
    String? onSurfaceVariant,
    String? outline,
    String? outlineVariant,
    String? shadow,
    String? scrim,
    String? inverseSurface,
    String? onInverseSurface,
    String? inversePrimary,
    String? surfaceTint,
  }) = _StacColorScheme;

  factory StacColorScheme.fromJson(Map<String, dynamic> json) =>
      _$StacColorSchemeFromJson(json);
}

extension StacColorSchemeParser on StacColorScheme {
  ColorScheme parse(BuildContext context) {
    return ColorScheme(
      brightness: brightness,
      primary: primary.toColor(context)!,
      onPrimary: onPrimary.toColor(context)!,
      primaryContainer: primaryContainer.toColor(context),
      onPrimaryContainer: onPrimaryContainer.toColor(context),
      primaryFixed: primaryFixed.toColor(context),
      primaryFixedDim: primaryFixedDim.toColor(context),
      onPrimaryFixed: onPrimaryFixed.toColor(context),
      onPrimaryFixedVariant: onPrimaryFixedVariant.toColor(context),
      secondary: secondary.toColor(context)!,
      onSecondary: onSecondary.toColor(context)!,
      secondaryContainer: secondaryContainer.toColor(context),
      onSecondaryContainer: onSecondaryContainer.toColor(context),
      secondaryFixed: secondaryFixed.toColor(context),
      secondaryFixedDim: secondaryFixedDim.toColor(context),
      onSecondaryFixed: onSecondaryFixed.toColor(context),
      onSecondaryFixedVariant: onSecondaryFixedVariant.toColor(context),
      tertiary: tertiary.toColor(context),
      onTertiary: onTertiary.toColor(context),
      tertiaryContainer: tertiaryContainer.toColor(context),
      onTertiaryContainer: onTertiaryContainer.toColor(context),
      tertiaryFixed: tertiaryFixed.toColor(context),
      tertiaryFixedDim: tertiaryFixedDim.toColor(context),
      onTertiaryFixed: onTertiaryFixed.toColor(context),
      onTertiaryFixedVariant: onTertiaryFixedVariant.toColor(context),
      error: error.toColor(context)!,
      onError: onError.toColor(context)!,
      errorContainer: errorContainer.toColor(context),
      onErrorContainer: onErrorContainer.toColor(context),
      surface: surface.toColor(context)!,
      onSurface: onSurface.toColor(context)!,
      surfaceDim: surfaceDim.toColor(context),
      surfaceBright: surfaceBright.toColor(context),
      surfaceContainerLowest: surfaceContainerLowest.toColor(context),
      surfaceContainerLow: surfaceContainerLow.toColor(context),
      surfaceContainer: surfaceContainer.toColor(context),
      surfaceContainerHigh: surfaceContainerHigh.toColor(context),
      surfaceContainerHighest: surfaceContainerHighest.toColor(context),
      onSurfaceVariant: onSurfaceVariant.toColor(context),
      outline: outline.toColor(context),
      outlineVariant: outlineVariant.toColor(context),
      shadow: shadow.toColor(context),
      scrim: scrim.toColor(context),
      inverseSurface: inverseSurface.toColor(context),
      onInverseSurface: onInverseSurface.toColor(context),
      inversePrimary: inversePrimary.toColor(context),
      surfaceTint: surfaceTint.toColor(context),
    );
  }
}
